const { DataTypes, Op } = require('sequelize')
const sequelize = require('../config/database')

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
    comment: '用户ID'
  },
  username: {
    type: DataTypes.STRING(50),
    allowNull: false,
    comment: '用户名',
    unique: 'users_username_unique'
  },
  password: {
    type: DataTypes.STRING(100),
    allowNull: false,
    comment: '密码'
  },
  name: {
    type: DataTypes.STRING(50),
    allowNull: false,
    comment: '姓名'
  },
  email: {
    type: DataTypes.STRING(100),
    allowNull: true,
    comment: '邮箱',
    unique: 'users_email_unique'
  },
  phone: {
    type: DataTypes.STRING(20),
    allowNull: true,
    comment: '手机号',
    unique: 'users_phone_unique'
  },
  avatar: {
    type: DataTypes.STRING(200),
    allowNull: true,
    comment: '头像URL'
  },
  role_id: {
    type: DataTypes.STRING(20),
    allowNull: true,
    defaultValue: 'normal_user',
    comment: '角色代码'
  },
  gender: {
    type: DataTypes.ENUM('male', 'female', 'other'),
    allowNull: true,
    comment: '性别'
  },
  status: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 0,
    comment: '状态（0待激活 1正常 2禁用）'
  },
  last_login: {
    type: DataTypes.DATE,
    allowNull: true,
    comment: '最后登录时间'
  },
  primary_department_id: {
    type: DataTypes.INTEGER,
    allowNull: true,
    references: {
      model: 'departments',
      key: 'id'
    }
  }
}, {
  tableName: 'users',
  timestamps: true,
  indexes: [
    {
      fields: ['role_id', 'status'],
      name: 'users_role_status_index'
    }
  ]
})

// 延迟设置关联关系，避免循环依赖
setTimeout(() => {
  const Department = require('./department')
  const UserDepartment = require('./userDepartment')
  const UserThirdParty = require('./userThirdParty')

  // 用户-部门多对多关联
  User.belongsToMany(Department, {
    through: UserDepartment,
    foreignKey: 'user_id',
    otherKey: 'department_id',
    as: 'departments'
  })

  // 用户-第三方平台关联
  User.hasMany(UserThirdParty, {
    foreignKey: 'user_id',
    as: 'thirdPartyAccounts'
  })
}, 0)

// 角色变更时的钩子函数
User.afterUpdate(async (user, options) => {
  if (user.changed('role_id')) {
    const transaction = options.transaction || await sequelize.transaction()
    
    try {
      await updateUserPermissions(user, { transaction })

      if (!options.transaction) {
        await transaction.commit()
      }
    } catch (error) {
      if (!options.transaction) {
        await transaction.rollback()
      }
      throw error
    }
  }
})

// 创建用户时的钩子函数
User.afterCreate(async (user, options) => {
  await updateUserPermissions(user)
})

// 统一处理用户权限更新的函数
async function updateUserPermissions(user, { transaction } = {}) {
  const PermissionTemplate = require('./PermissionTemplate')
  const UserPermission = require('./userPermission')
  const UserDepartment = require('./userDepartment')

  try {
    // 根据角色代码获取对应的权限模板
    const templateCode = `${user.role_id}_template`

    const template = await PermissionTemplate.findOne({
      where: { code: templateCode },
      transaction
    })

    if (!template) return

    // 如果是部门管理员，需要确认用户属于某个部门
    if (user.role_id === 'dept_admin') {
      const userDepartment = await UserDepartment.findOne({
        where: { 
          user_id: user.id,
          department_id: user.primary_department_id
        },
        transaction
      })

      if (!userDepartment) {
        console.warn(`User ${user.id} is set as dept_admin but has no primary department`)
        return
      }

      // 更新用户权限，加入部门范围
      const permissions = {
        ...template.permissions,
        data: {
          ...template.permissions.data,
          department_id: user.primary_department_id
        }
      }

      await UserPermission.upsert({
        user_id: user.id,
        template_id: template.id,
        permissions
      }, { transaction })
    } else {
      // 其他角色直接使用模板权限
      await UserPermission.upsert({
        user_id: user.id,
        template_id: template.id,
        permissions: template.permissions
      }, { transaction })
    }
  } catch (error) {
    console.error('Update user permission error:', error)
    throw error
  }
}

module.exports = User 